#include "stdafx.h"
#include "CppUnitTest.h"
#include <HSModel/Ground.h>
#include <HSModel/WorldInfoController.h>
#include <HSModel/Bench.h>
#include <HSModel/SharedConstants.h>
#include <HSModel/Model3DStorage.h>
#include <HSModel/World.h>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace HSModelTests
{
	TEST_CLASS(BenchTests)
	{
  public:
		TEST_METHOD(BenchShouldFaceWalkway)
		{
    /* ---- Arrange ---- */
    HeightMap height_map = HeightMap(GroundConstants::CELL_COUNT + 1, GroundConstants::CELL_COUNT + 1);
    GeneratedHeightMapWithDiamondSquare(height_map, GroundConstants::PLAINS_PERCENTAGE, GroundConstants::MAX_HEIGHT);
    Ground ground(height_map, GroundConstants::CELL_SIZE, GroundConstants::WATER_LEVEL);
    World world(HeightMap(1, 1));

    /*
     * .................
     * : W       W   W :
     * :               :
     * : W       1   W :
     * :               :
     * : W       4   W :
     * :               :
     * : W   2   3   W :
     * :               :
     * : W   W   W   W :
     * .................
     *
     * Walkway squares marked with "W"
     * Squares with benches marked with numbers 1-4 
     */

    ground.CreateWalkway(TVector2(0, 0) * GroundConstants::CELL_SIZE);
    ground.CreateWalkway(TVector2(0, 1) * GroundConstants::CELL_SIZE);
    ground.CreateWalkway(TVector2(0, 2) * GroundConstants::CELL_SIZE);
    ground.CreateWalkway(TVector2(0, 3) * GroundConstants::CELL_SIZE);
    ground.CreateWalkway(TVector2(1, 0) * GroundConstants::CELL_SIZE);
    ground.CreateWalkway(TVector2(2, 0) * GroundConstants::CELL_SIZE);
    ground.CreateWalkway(TVector2(3, 0) * GroundConstants::CELL_SIZE);
    ground.CreateWalkway(TVector2(4, 0) * GroundConstants::CELL_SIZE);
    ground.CreateWalkway(TVector2(1, 3) * GroundConstants::CELL_SIZE);
    ground.CreateWalkway(TVector2(2, 3) * GroundConstants::CELL_SIZE);
    ground.CreateWalkway(TVector2(3, 3) * GroundConstants::CELL_SIZE);
    ground.CreateWalkway(TVector2(4, 3) * GroundConstants::CELL_SIZE);
    ground.CreateWalkway(TVector2(4, 2) * GroundConstants::CELL_SIZE);

    WorldInfoController wic(ground, std::map<std::string, IRenderable*>());

    Bench bench1(world, wic);
    Bench bench2(world, wic);
    Bench bench3(world, wic);
    Bench bench4(world, wic);

    bench1.SetPosition(TVector3(3.5, 2.5, 0) * GroundConstants::CELL_SIZE);
    bench2.SetPosition(TVector3(1.5, 1.5, 0) * GroundConstants::CELL_SIZE);
    bench3.SetPosition(TVector3(1.5, 2.5, 0) * GroundConstants::CELL_SIZE);
    bench4.SetPosition(TVector3(2.5, 2.5, 0) * GroundConstants::CELL_SIZE);

    double exp_angle1 = 90.0;
    double exp_angle2 = 180.0;
    double exp_angle3 = 270.0;
    double exp_angle4 = 0.0;

    /* ---- Act ---- */
    double act_angle1 = bench1.GetAngleAroundY();
    double act_angle2 = bench2.GetAngleAroundY();
    double act_angle3 = bench3.GetAngleAroundY();
    double act_angle4 = bench4.GetAngleAroundY();

    /* ---- Assert ---- */
    Assert::AreEqual(exp_angle1, act_angle1);
    Assert::AreEqual(exp_angle2, act_angle2);
    Assert::AreEqual(exp_angle3, act_angle3);
    Assert::AreEqual(exp_angle4, act_angle4);
		}

    TEST_METHOD(BenchShouldNotRotateAfterAddingAnotherWalkwayNearby)
      {
      World world(HeightMap(5,5));
      world.GetGround()->CreateWalkway(TVector2(0, 0)); // 0, 0 cell
      Bench bench(world, *world.GetWorldInfoController());
      bench.SetPosition(0, 1 * GroundConstants::CELL_SIZE, 0); // 0, 1 cell

      double angle = bench.GetAngleAroundY();

      // Place another walkway
      world.GetGround()->CreateWalkway(TVector2(1 * GroundConstants::CELL_SIZE, 1 * GroundConstants::CELL_SIZE)); // 1, 1 cell

      // Assert angle is the same

      Assert::AreEqual(angle, bench.GetAngleAroundY());
      }

	};
}